package com.yunhe.policyfulfillment.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.yunhe.common.constant.SystemConsts;
import com.yunhe.common.util.RSAUtil;
import com.yunhe.policyfulfillment.authority.domain.PolicyCompanyUser;
import com.yunhe.policyfulfillment.authority.domain.PolicyUser;

import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName JwtUtil
 * @Description TODO
 * @Author HeTao
 * @Date 2021/7/21 15:53
 * @Version 1.0
 **/
public class JwtUtil {

    private static final String PRIVATE_KEY_STRING = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC+vB8ji8Od19y6VBssY8vOQPKXkzY9NUGQs/dmTXMyJ2f8IvdVzScOzSzTAYuuQErwQ5+eL4tbiUJ5VRrH515ow4TBGjju6zxO7qX8W6qt8IjkR/AsJLLUG3CGNbpqjJEG+Wd4hm7ePJVfC95I8hzX0/HmAvCquYDn5O7uW/4l4M/9fhbT5v9dXlSev/DJVtD9//ypmOkFn7AddeoWwWYMpo2Y+7CKS10t0ovdXgs7zWAV1g01jlg54kU+LTZO47s5pV7Z+pM1ruoFsU5yvYo9iu/5Z/ZUNN2RdrVi4vYBWijlRCY3x2sPmxkMYAOuD9PMQNVTzqYDYO1y76p7IrujAgMBAAECggEAL61ao0oGheg1lqX7fOcdRNtbSKRVxIsRbpht2Ta2+ux6w74B0YLMppiHAd+7CL2tfc2JksMTtLfk0+uAHEQrh0iIYLSrUp2en6Rr/V70lTIxJc8NrBsoUHjjccjwZj3o6rNhN/FyuT6vn+iZkeZja1fhebt2aVahcFX7m72HE/RlfaC7jd2vk9nyeJW6fnxPzKt+ThW3l/aE21jgNlY360w16d40aQ5EZNeh6UDO5o4k8R2hXRpTA0LheLrFXURN4k/Rw72Hxf2DdVLq7JpnbTxEu8ukOhy3RgxpJcI9BEMakua6P1s1OQbbkRqXhpaqRJnGWr47oPPivtVzncWBIQKBgQDujQqBhwRIS5bUTS4+LaiIpTmw1NWKicHsIMcipPuQdBtVkEF2B9Qhi0lZxawjqkHHTIzqGxYWQxnREx6I3Q8n9lZG2Yool2Jgaa/6T0CUAQJDzVoB5JeoKdaCPCgLUFwReBVfY4MYNy03rdLyBA9yQ6LqGPtjVKBGJKU2SfRNmwKBgQDMr7Sqmygzd4SU8BXabBGSTyjTAqy3D+nxFqCow/auGT64zG/fEpEGpHEmU8jnrBg/MXIad0Rn4aA3+rwyfdZGtnPg2Hn83MlXtxir4CWLYqMVHxQMiVo9xNRf/3QlYNMavUQS5k8Q3W22/WFlx+iNXOxh3HX2R59feSsBaLOumQKBgG/Sm6cmJGLDVDvGxjONcaBEW2vCCSu88bN/lflufyIy2xFb4uOyPcVPpp23ZL7/M4B6KOAgvFTJNZPlM34SqeUgu0bQ+MuYUxxAzqY2el4mruobm+KhRlok6pH4IwlSrSXfNZ2WZ0B1tPORvv2F27vDat3zwfvJEqxuxydQuX2bAoGBALSea7eMmMnpsnXW8gG/ETZhYe3p00zq3w4eYIDsA7aXklByHlnjQVRyMWKX1pYQt4iz8jNGgXeFkuMy/3Uys63MfK6xd9vZXFZpvHyWm6rGzI/rz75MSfRtxtY7TltZeI+E6hgfYS/JpXIvXw34fM6ZbAHjD7jWdN1Dx95DbSMpAoGAHgc/AUyuCTJQLpYFH8EJpfqSVeZjnOdIMuQ7WUTnujRMpYhIDa4CT6ozQUzJ0M0u4xYSZTFLy3IOQKyPqqZlVy5pRhLIYsEDybpuTEg24nd0QDm4u3maZUQC51MwrSmuCD1qIMk4d3eq+KH1aLEa9mrIyHKPAl6UhM2gW6/kdMA=";
    private static final String PUBLIC_KEY_STRING = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvrwfI4vDndfculQbLGPLzkDyl5M2PTVBkLP3Zk1zMidn/CL3Vc0nDs0s0wGLrkBK8EOfni+LW4lCeVUax+deaMOEwRo47us8Tu6l/FuqrfCI5EfwLCSy1BtwhjW6aoyRBvlneIZu3jyVXwveSPIc19Px5gLwqrmA5+Tu7lv+JeDP/X4W0+b/XV5Unr/wyVbQ/f/8qZjpBZ+wHXXqFsFmDKaNmPuwiktdLdKL3V4LO81gFdYNNY5YOeJFPi02TuO7OaVe2fqTNa7qBbFOcr2KPYrv+Wf2VDTdkXa1YuL2AVoo5UQmN8drD5sZDGADrg/TzEDVU86mA2Dtcu+qeyK7owIDAQAB";

    public static Map<String, String> parseToken(String token) {
        try {
            Algorithm algorithm;
            try {
                RSAPrivateKey privateKey = RSAUtil.getPrivateKey(PRIVATE_KEY_STRING);
                RSAPublicKey publicKey = RSAUtil.getPublicKey(PUBLIC_KEY_STRING);
                algorithm = Algorithm.RSA256(publicKey, privateKey);
            } catch(Exception e) {
                return null;
            }
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token);
            Claim userName = jwt.getClaim(SystemConsts.HEADER.USER_NAME.value());
            Claim userId = jwt.getClaim(SystemConsts.HEADER.USER_ID.value());
            Map<String, String> map = new HashMap<>(2);
            map.put("userName", userName.isNull() ? null : userName.asString());
            map.put(SystemConsts.HEADER.USER_ID.value(), userId.isNull() ? null : userId.asString());
            return map;
        } catch (JWTVerificationException exception) {
            return null;
        }
    }

    public static String getToken(String  userName,String userId) {
        //设置过期时间
        Date expires = new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000);
        Algorithm algorithm;
        try {
            RSAPrivateKey privateKey = RSAUtil.getPrivateKey(PRIVATE_KEY_STRING);
            RSAPublicKey publicKey = RSAUtil.getPublicKey(PUBLIC_KEY_STRING);
            algorithm = Algorithm.RSA256(publicKey, privateKey);
        } catch(Exception e) {
            e.printStackTrace();
            return null;
        }
        return JWT.create().withExpiresAt(expires)
                .withAudience(String.valueOf(userId))
                .withClaim(SystemConsts.HEADER.USER_NAME.value(), userName)
                .withClaim(SystemConsts.HEADER.USER_ID.value(), userId)
                .sign(algorithm);
    }

    public static String getToken(PolicyUser policyUser) {
        //设置过期时间
        Date expires = new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000);
        Algorithm algorithm;
        try {
            RSAPrivateKey privateKey = RSAUtil.getPrivateKey(PRIVATE_KEY_STRING);
            RSAPublicKey publicKey = RSAUtil.getPublicKey(PUBLIC_KEY_STRING);
            algorithm = Algorithm.RSA256(publicKey, privateKey);
        } catch(Exception e) {
            e.printStackTrace();
            return null;
        }
        return JWT.create().withExpiresAt(expires)
                .withAudience(String.valueOf(policyUser.getId()))
                .withClaim(SystemConsts.HEADER.USER_NAME.value(), policyUser.getUserName())
                .withClaim(SystemConsts.HEADER.USER_ID.value(), String.valueOf(policyUser.getId()))
                .withClaim(SystemConsts.HEADER.ROLE_ID.value(), policyUser.getRoleName())
                .withClaim(SystemConsts.HEADER.ORG_ID.value(), policyUser.getOrgId())
                .sign(algorithm);
    }

    public static String getToken(PolicyCompanyUser policyCompanyUser) {
        //设置过期时间
        Date expires = new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000);
        Algorithm algorithm;
        try {
            RSAPrivateKey privateKey = RSAUtil.getPrivateKey(PRIVATE_KEY_STRING);
            RSAPublicKey publicKey = RSAUtil.getPublicKey(PUBLIC_KEY_STRING);
            algorithm = Algorithm.RSA256(publicKey, privateKey);
        } catch(Exception e) {
            e.printStackTrace();
            return null;
        }
        return JWT.create().withExpiresAt(expires)
                .withAudience(String.valueOf(policyCompanyUser.getId()))
                .withClaim(SystemConsts.HEADER.USER_NAME.value(), policyCompanyUser.getUserAccount())
                .withClaim(SystemConsts.HEADER.USER_ID.value(), String.valueOf(policyCompanyUser.getId()))
                .withClaim(SystemConsts.HEADER.ORG_ID.value(), policyCompanyUser.getOrgId())
                .sign(algorithm);
    }
}
